package com.hy;

import com.hy.pojo.InterviewRecord;
import com.hy.pojo.Job;
import com.hy.pojo.bo.AnswerBO;
import com.hy.pojo.bo.SubmitAnswerBO;
import com.hy.pojo.glm.EventType;
import com.hy.pojo.glm.GLMResponseV3;
import com.hy.service.InterviewRecordService;
import com.hy.service.JobService;
import com.hy.utils.GLMTokenUtils;
import com.hy.utils.JsonUtils;
import com.hy.utils.ChatGLMUtils;
import com.hy.utils.HttpConstants;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.internal.sse.RealEventSource;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Nullable;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @ClassName ChatGLMTask
 * @Author 公众号【风间影月】
 * @Version 1.0
 * @Description ChatGLMTask 用于提供异步调用的任务
 **/
@Component
@Slf4j
public class ChatGLMTask {

    @Resource
    private JobService jobService;

    @Resource
    private InterviewRecordService interviewRecordService;

    @Async
    public void display(SubmitAnswerBO submitAnswerBO) {
        log.info("开始异步AI智能分析...");

        /********** 拼接提示词与回答的文字内容 **********/
        // 1. 获得职位提示词前缀
        String jobId = submitAnswerBO.getJobId();
        Job job = jobService.getDetails(jobId);
        // 获得职位名称
        String prompt = job.getPrompt();

        // 2. 组装问题内容
        List<AnswerBO> answerList = submitAnswerBO.getQuestionAnswerList();
        StringBuilder contentBuilder = new StringBuilder();
        for (AnswerBO answer : answerList) {
            contentBuilder.append("提问：").append(answer.getQuestion()).append("\n");
            contentBuilder.append("正确答案：").append(answer.getReferenceAnswer()).append("\n");
            contentBuilder.append("回答内容：").append(answer.getAnswerContent()).append("\n\n");
        }

        String submitContent = prompt + "\n\n" + contentBuilder.toString();
        System.out.println(submitContent);


        /********** 把内容提交到ChatGLM进行分析 **********/
        Request request = new Request.Builder()
                .url(ChatGLMUtils.API_URL)
                .header("Authorization", GLMTokenUtils.generateToken())
                .header("Content-Type", HttpConstants.JSON_CONTENT_TYPE)
                .header("User-Agent", HttpConstants.DEFAULT_USER_AGENT)
                .header("Accept", HttpConstants.SSE_CONTENT_TYPE)
                .post(RequestBody.create(MediaType.parse("application/json"), ChatGLMUtils.generateBodyString(submitContent)))
                .build();


        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(HttpConstants.CONNECT_TIMEOUT, HttpConstants.TIMEOUT_UNIT)
                .writeTimeout(HttpConstants.WRITE_TIMEOUT, HttpConstants.TIMEOUT_UNIT)
                .readTimeout(HttpConstants.READ_TIMEOUT, HttpConstants.TIMEOUT_UNIT)
                .build();

        // 实例化EventSource，并注册EventSource监听器
        RealEventSource realEventSource = getRealEventSource(
                contentBuilder.toString(),
                submitAnswerBO.getCandidateId(),
                job.getJobName(),
                submitAnswerBO.getTotalSeconds(),
                request);
        realEventSource.connect(okHttpClient);
    }

    private RealEventSource getRealEventSource(String answerContent, String candidateId, String jobName,Integer takeTime, Request request) {
        // 实例化EventSource，并注册EventSource监听器
        RealEventSource realEventSource = new RealEventSource(request, new EventSourceListener() {

            String finalResult = "";

            @Override
            public void onEvent(EventSource eventSource, @Nullable String id, @Nullable String type, String data) {
                GLMResponseV3 response = JsonUtils.jsonToPojo(data, GLMResponseV3.class);
                String result = response.getData();
                finalResult += result;

                // type消息类型：add-增量、finish-结束、error-错误、interrupted-中断
                if (EventType.finish.key.equals(type)) {
                    InterviewRecord record = new InterviewRecord();
                    record.setCandidateId(candidateId);
                    record.setTakeTime(takeTime);
                    record.setJobName(jobName);
                    record.setAnswerContent(answerContent);
                    record.setResult(finalResult);
                    record.setCreateTime(LocalDateTime.now());
                    record.setUpdatedTime(LocalDateTime.now());

                    interviewRecordService.save(record);

                    if (eventSource != null) {
                        eventSource.cancel();
                    }
                }
            }

            @Override
            public void onClosed(EventSource eventSource) {
                System.out.println("关闭链接事件");
            }

            @Override
            public void onOpen(EventSource eventSource, Response response) {
                System.out.println("打开链接事件");
            }

            @Override
            public void onFailure(EventSource eventSource, @Nullable Throwable t, @Nullable Response response) {
                System.out.println("失败事件");
            }
        });
        return realEventSource;
    }
}